﻿#include <iostream>
class MoveObject {
public:
    virtual void test(){}
    virtual void move() {
        //if(dynamic_cast<MonsterObject*>(this))//不违反语法规定，但是逻辑非常依赖派生类，非常不推荐
        std::cout << "MoveObject" << std::endl;
    }
};
class MonsterObject :public MoveObject {
public:
    void MonsterMove() {};
    void move() {
        std::cout << "MonsterObject" << std::endl;
    }
};
class MObject :public virtual MoveObject {};//虚基类
class BOSS {};
class NPCObject :public MoveObject {
public:
    void NPCMove() {};
    void move() {
        std::cout << "NPCObject" << std::endl;
    }
};
class WOLF :public MonsterObject {};
class MAN :public MonsterObject {};
class WOLFMAN :public WOLF, public BOSS {};

//class BOSS{};

int main()
{
    MonsterObject monster;
    MoveObject* _move = (MoveObject*)&monster;//强制转换

    MoveObject* obj= &monster;

    MoveObject& lMove = monster;//引用转换
    //_move = new MoveObject();
    MonsterObject* _pmonsterA = static_cast<MonsterObject*>(_move);//静态类型转换，如果从基类MoveObject转换，虽然不报错，但是有风险，因为基类转派生类有内存泄露的可能
    
    MonsterObject* _pmonsterB=dynamic_cast<MonsterObject*>(_move);//需要有虚函数表示多态才不报错，若_move指向MoveObject则返回nullptr表示转换失败，若_move指向MonsterObject则返回地址表示转换成功，原因还是因为基类MoveObject转换，虽然不报错，但是有风险，因为基类转派生类有内存泄露的可能
    if (_pmonsterB == nullptr)
        std::cout << "转换失败！" << std::endl;
    else
        std::cout << "转换成功！" << std::endl;

    //写法没错，但是没有利用到多态的特性，过度使用dynamic_cast
    auto _pmonsterC=dynamic_cast<MonsterObject*>(_move);
    auto _pNPCA = dynamic_cast<NPCObject*>(_move);
    //if (_pmonsterC != nullptr)_pmonsterC->MonsterMove();
    if (_pNPCA != nullptr)_pNPCA->NPCMove();
    
    //使用多态，在基类MoveObject添加move虚函数，派生类实现move函数，然后多态调用
    _move->move();
    NPCObject Npc;
    _move = (MoveObject*)&Npc;
    _move->move();

    MoveObject& lMove1 = dynamic_cast<MoveObject&>(monster);

    //MonsterObject monster;
    //NPCObject& lNPC = dynamic_cast<NPCObject&>(monster);//抛出异常，但是可以过编译，指针可以有空指针，引用不能有空引用，此时因为基类转派生类导致转换失败返回空指针，所以异常

    WOLFMAN wlfMan;
    MoveObject* pMove = &wlfMan;
    auto p = dynamic_cast<WOLFMAN*>(pMove);//转换是否成功取决于pMove是否指向WOLFMAN
    std::cout << p << std::endl;
    auto b = dynamic_cast<BOSS*>(pMove);//跨类型转换，WOLFMAN没有继承BOSS的话返回空指针
    std::cout << b << std::endl;

    

}